/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_framework/zhiqim_kernel.htm
 *
 * Zhiqim Kernel is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.zhiqim.kernel.util;

import java.security.SecureRandom;
import java.util.Random;

import org.zhiqim.kernel.annotation.AnAlias;
import org.zhiqim.kernel.constants.SignConstants;

/**
 * 随机相关工具类
 * 
 * 两种取随机数方式
 * 1、Random，
 * 2、SecureRandom
 * 
 * 两种操作方式
 * 1、支持传入内容取随机数
 * 2、提供默认的6种取随机数
 *
 * @version v1.0.0 @author zouzhigang 2014-2-27 新建与整理
 * @version v1.0.1 @author zouzhigang 2017-4-20 增加安全随机数和传入内容取随机数
 */
@AnAlias("Randoms")
public class Randoms implements SignConstants
{
    /** 随机生成一定长度的数字 */
    public static String digits(int length)
    {
        return random(length, _DIGITS_, false);
    }
    
    /** 随机生成一定长度的数字 */
    public static String digitsSecure(int length)
    {
        return random(length, _DIGITS_, true);
    }
    
    /** 随机生成一定长度的大写字母 */
    public static String upperLetters(int length)
    {
        return random(length, _LETTERS_UPPERCASE_, false);
    }
    
    /** 随机生成一定长度的大写字母 */
    public static String upperLettersSecure(int length)
    {
        return random(length, _LETTERS_UPPERCASE_, true);
    }
    
    /** 随机生成一定长度的小写字母 */
    public static String lowerLetters(int length)
    {
        return random(length, _LETTERS_LOWERCASE_, false);
    }
    
    /** 随机生成一定长度的小写字母 */
    public static String lowerLettersSecure(int length)
    {
        return random(length, _LETTERS_LOWERCASE_, true);
    }
    
    /** 随机生成一定长度的小写字母和数字 */
    public static String lowerLettersDigits(int length)
    {
        return random(length, _LETTERS_LOWERCASE_DIGITS_, false);
    }
    
    /** 随机生成一定长度的小写字母和数字 */
    public static String lowerLettersDigitsSecure(int length)
    {
        return random(length, _LETTERS_LOWERCASE_DIGITS_, true);
    }
    
    /** 随机生成一定长度的字母 */
    public static String letters(int length)
    {
        return random(length, _LETTERS_, false);
    }
    
    /** 随机生成一定长度的字母 */
    public static String lettersSecure(int length)
    {
        return random(length, _LETTERS_, true);
    }
    
    /** 随机生成一定长度的字母或数字 */
    public static String lettersDigits(int length)
    {
        return random(length, _LETTERS_DIGITS_, false);
    }
    
    /** 随机生成一定长度的字母或数字 */
    public static String lettersDigitsSecure(int length)
    {
        return random(length, _LETTERS_DIGITS_, true);
    }

    /** 随机生成一定长度的特殊字符 */
    public static String symbol(int length)
    {
        return random(length, _SYMBOL_F_, false);
    }
    
    /** 随机生成一定长度的特殊字符 */
    public static String symbolSecure(int length)
    {
        return random(length, _SYMBOL_F_, true);
    }
    
    /**
     * 随机生成一定长度的字符或数字
     * 
     * @param length    长度
     * @param content   指定内容，如"0123456"取2位长度的随机数
     * @return          随机字符串
     */
    public static String random(int length, String content)
    {
        return random(length, content, false);
    }
    
    /**
     * 随机生成一定长度的字符或数字
     * 
     * @param length    长度
     * @param content   指定内容，如"0123456"取2位长度的随机数
     * @param secure    是否使用安全随机数
     * @return          随机字符串
     */
    public static String random(int length, String content, boolean secure)
    {
        int len = content.length();
        
        StringBuilder strb = new StringBuilder();
        Random random = secure?new SecureRandom():new Random();
        for (int i=0;i<length;i++)
        {
            int index = random.nextInt(len);
            strb.append(content.charAt(index));
        }
        
        return strb.toString();
    }
    
    /**
     * 随机生成一定长度的字符或数字
     * 
     * @param length    长度
     * @param type      类型，是字母数字(0),数字(1),字母(2),大写字母(3),小写字母(4),大写字母和数字(5),小写字母和数字(6)
     * @return          随机字符串
     */
    public static String random(int length, int type)
    {
        return random(length, type, false);
    }
    
    /**
     * 随机生成一定长度的字符或数字
     * 
     * @param length    长度
     * @param type      类型，是字母数字(0),数字(1),字母(2),大写字母(3),小写字母(4),大写字母和数字(5),小写字母和数字(6)
     * @param secure    是否使用安全随机数
     * @return          随机字符串
     */
    public static String random(int length, int type, boolean secure)
    {
        if (length < 1)
            return _EMPTY_;
        
        String content = null;
        switch (type)
        {
        case 1: content = _DIGITS_;break;
        case 2: content = _LETTERS_;break;
        case 3: content = _LETTERS_UPPERCASE_;break;
        case 4: content = _LETTERS_LOWERCASE_;break;
        case 5: content = _LETTERS_UPPERCASE_ + _DIGITS_;break;
        case 6: content = _LETTERS_LOWERCASE_ + _DIGITS_;break;
        default:content = _LETTERS_DIGITS_;break;
        }
        
        return random(length, content, secure);
    }
}
